home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: nntp.coast.net!torn!sq!msb
- From: msb@sq.com (Mark Brader)
- Subject: Re: routine for yesterday's date
- Message-ID: <1996Mar30.043002.19054@sq.com>
- Organization: SoftQuad Inc., Toronto, Canada
- References: <315c4d0f.19874776@ottnews.shl.com>
- Date: Sat, 30 Mar 1996 04:30:02 GMT
-
- Bruce Coghill (75323.455@compuserve.com) writes at 2:48 PM, March 29, 1996:
-
- > In my C manual the time.h and time functions are described
- > and how I can pull off each element in the structure (like year,
- > month, day, day-of-the-year), but it isn't clear to me how to subtract
- > a day.
-
- This is question 13.14 on the FAQ list, but I'd like to expand a bit
- on what it says there.
-
- Bruce, you have gotten as far as calling time() and localtime(). The
- next thing is to use the normalizing feature of mktime(). Suppose that
- you have a variable of type struct tm called x, and you've just put the
- current time into it using localtime(). Now you basically just want to
- do something like this:
-
- x.tm_day--; /* back 1 day */
- (void) mktime (&x); /* normalize */
-
- And probably someone is going to post to suggest just that. The above
- code will work most of the time, but it has two problems. First, mktime()
- is allowed to fail, so it's as well to check for it and report the error.
-
- Second, it finds the date 24 hours ago. If there was a daylight saving
- time transition, 24 hours ago might be today or the day before yesterday.
-
- You might think to fix the first problem by adding the line:
-
- x.tm_isdst = -1;
-
- at the top, effectively forcing mktime() to work by wall clock time.
- Now you are asking for the same time yesterday, rather than the time 24
- hours ago. But this doesn't fix the problem -- in the case of a daylight
- saving time transition, "the same time yesterday" might be ambiguous or
- not exist. In such a case a failure of mktime() is allowed (or perhaps
- required, depending on how one interprets the standard).
-
- The correct fix is to let the daylight saving time transition take its
- effect by leaving tm_isdst alone, but to ask for the time 24 hours before
- a time near noon today. Even if that time is 11 am or 1 pm, it will still
- be yesterday. So the final version of the code is:
-
- x.tm_day--; /* back 1 day (well, 24 hours) */
- x.tm_hour = 12; /* from some time between noon and 1 pm */
-
- /* and normalize */
- if (mktime (&x) == (time_t) -1) {
- fprintf (stderr, "mktime failed!!\n");
- exit(1);
- }
-
- The structure now contains the correct year, month, and day values for
- yesterday. As always, remember that the representation of a struct tm
- requires you to add 1900 to the year and 1 to the month to get the correct
- values if displaying them numerically.
-
- There is a terser version of the "final" code: replace the first two lines by
-
- x.tm_hour = -12; /* 12 hours before sometime between
- * midnight and 1 am this morning */
-
- but the meaning of this is less obvious, so I don't recommend it.
-
- --
- Mark Brader "To err is human, but to really mess things up
- msb@sq.com you need a timetable planner!"
- SoftQuad Inc., Toronto -- Richard Porter
-
- My text in this article is in the public domain.
-